package com.aiyige.page.webview;

import android.app.Activity;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.webkit.JavascriptInterface;
import android.widget.FrameLayout;

import com.aiyige.BuildConfig;
import com.aiyige.page.webview.event.EventPreload;
import com.aiyige.page.webview.model.PreloadTask;
import com.aiyige.page.webview.model.PreloadTaskQueue;
import com.just.agentwebX5.AgentWebX5;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebStorage;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import org.apache.commons.collections4.queue.CircularFifoQueue;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class PreloadWebView extends FrameLayout {
    AgentWebX5 webview;
    PreloadTaskQueue queue;
    CircularFifoQueue<PreloadTask> preloadHistroy;
    Handler mainHandler;
    WorkerThread workerThread;

    public PreloadWebView(@NonNull Context context) {
        super(context);
        init();
    }

    public PreloadWebView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PreloadWebView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init() {
        mainHandler = new Handler(Looper.getMainLooper());
        webview = AgentWebX5.with((Activity) getContext())//
                .setAgentWebParent(this, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))//
                .closeProgressBar()
                .setWebSettings(WebSettingsManager.getInstance())
                .setWebViewClient(createWebViewClient())
                .setWebChromeClient(createWebChromeClient())
                .setSecutityType(AgentWebX5.SecurityType.default_check)
                .createAgentWeb()//
                .ready()
                .go(BuildConfig.PRELOAD_H5_PAGE);
    }

    private WebViewClient createWebViewClient() {
        return new WebViewClient();
    }

    private WebChromeClient createWebChromeClient() {
        return new WebChromeClient();
    }


    public void onCreate() {
        queue = new PreloadTaskQueue();
        preloadHistroy = new CircularFifoQueue<>(200);
        workerThread = new WorkerThread();
        workerThread.start();
        try {
            EventBus.getDefault().register(this);
        } catch (Exception e) {
        }
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onEvent(EventPreload event) {
        queue.submitTask(event.getTask());
    }


    public void onDestroy() {
        try {
            EventBus.getDefault().unregister(this);
        } catch (Exception e) {
        }
        workerThread.shutdown();
        WebStorage.getInstance().deleteAllData();
        webview.getWebLifeCycle().onDestroy();
    }

    public void doPreload(final String url) {
        mainHandler.post(new Runnable() {
            @Override
            public void run() {
                webview.getLoader().loadUrl(url);
            }
        });
    }

    public class WorkerThread extends Thread {
        Lock mutex;
        Condition waitCondition;
        volatile boolean stopWork = false;

        public WorkerThread() {
            mutex = new ReentrantLock();
            waitCondition = mutex.newCondition();
        }

        @Override
        public void run() {
            try {
                outLoop:
                while (true) {
                    PreloadTask task = queue.getTask();
                    if (task == null) continue;
                    switch (task.getType()) {
                        case PreloadTask.TYPE_INFO:
                        case PreloadTask.TYPE_MAJOR_COURSE:
                        case PreloadTask.TYPE_UNKNOWN:
                            if (preloadHistroy.contains(task)) continue;
                            preloadHistroy.add(task);
                            doPreload(task.getUrl());
                            break;
                        case PreloadTask.TYPE_SHUTDOWN:
                            break outLoop;
                        default:
                            continue;
                    }
                    try {
                        mutex.lock();
                        if (stopWork) {
                            mutex.unlock();
                            break outLoop;
                        }
                        waitCondition.await(3, TimeUnit.SECONDS);
                    } catch (Exception e) {

                    }
                    try {
                        mutex.unlock();
                    } catch (Exception ex) {

                    }
                }
            } catch (Exception e) {
            }
        }

        public void shutdown() {
            queue.submitTask(PreloadTask.newBuilder().type(PreloadTask.TYPE_SHUTDOWN).build());
            mutex.lock();
            stopWork = true;
            waitCondition.signalAll();
            mutex.unlock();
            try {
                join();
            } catch (Exception e) {
            }
        }
    }
}
